package com.cdelink.xzgy.ftp.user.controller;

import com.cdelink.xzgy.ftp.annotation.Authorized;
import com.cdelink.xzgy.ftp.common.ReturnData;
import com.cdelink.xzgy.ftp.user.entity.Records;
import com.cdelink.xzgy.ftp.user.entity.dto.FileDto;
import com.cdelink.xzgy.ftp.user.entity.vo.FileVo;
import com.cdelink.xzgy.ftp.user.service.FileService;
import com.cdelink.xzgy.ftp.user.service.impl.RecordServiceImpl;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import springfox.documentation.annotations.ApiIgnore;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.util.List;
import java.util.Map;

/**
 * (User)表控制层
 *
 * @author sxl
 * @since 2021-12-13 17:14:21
 */
@Api(tags = "文件相关")
@RestController
@RequestMapping
public class FileController {
    /**
     * 服务对象
     */
    @Resource
    private FileService fileService;
    @Autowired
    HttpServletResponse response;
    @Autowired
    HttpSession session;


    /**
     * @param folder
     * @return
     */
    @ApiOperation(value = "获取ftp中所有文件夹/文件列表", notes = "查询所有文件夹")
    @Authorized
    @GetMapping("/files")
    public ReturnData listFiles(@RequestParam(required = false) @ApiParam("无：不传 根路径示例：/ftptest 多层级示例：/ftptest/y") String folder) {
        List<FileVo> ftpFiles = fileService.listFiles(folder);
        return ReturnData.ok(ftpFiles);
    }

    /**
     * @param folder
     * @return
     */
    @ApiOperation(value = "(递归)获取ftp中所有文件夹/文件列表", notes = "(递归)获取ftp中所有文件夹/文件列表")
    @GetMapping("/fileList")
    public ReturnData fileList(@RequestParam(required = false) @ApiParam("无：不传 根路径示例：/ftptest 多层级示例：/ftptest/y") String folder) {
        FileDto fileDto = fileService.getFileList(folder);
        return ReturnData.ok(fileDto);
    }


    /**
     * 校验文件是否有重复
     *
     * @param data
     * @return
     */
    @ApiOperation(value = "校验文件在当前文件夹内是否有重复", notes = "校验文件是否有重复")
    @Authorized
    @PostMapping(value = "/checkRepeat")
    public ReturnData checkRepeat(@RequestBody Map<String, String> data) {
        boolean result = fileService.checkRepeat(data.get("folder"), data.get("fileName"));
        return ReturnData.ok((result) ? "有重复" : "无重复").setData(result);
    }

    /**
     * 新文件上传
     *
     * @param file
     * @param folder
     * @param insertOrCover
     * @param exist
     * @param userId
     * @param taskId
     * @return
     */
    @ApiOperation(value = "文件上传", notes = "文件上传")
    @Authorized
    @PostMapping(value = "/upload", consumes = "multipart/*")
    public ReturnData upload(@ApiParam(value = "选择上传文件", required = true) MultipartFile file,
                             @ApiParam(value = "文件夹名") @RequestParam String folder,
                             @ApiParam(value = "状态(1:覆盖 2:新增)", required = true) @RequestParam Integer insertOrCover,
                             @ApiParam(value = "是否存在(true:存在 false:不存在)", required = true) @RequestParam boolean exist,
                             @ApiIgnore @RequestAttribute String userId,
                             @ApiParam(value = "任务id") @RequestParam String taskId) {
        System.out.println("进入文件上传接口" + taskId);
        return fileService.uploadFile(file, folder, insertOrCover, exist, userId, taskId);
    }

    /**
     * 终止文件上传
     *
     * @param taskId
     * @return
     */
    @ApiOperation(value = "终止文件上传", notes = "文件上传")
    @Authorized
    @GetMapping(value = "/stop")
    public ReturnData stop(@ApiParam(value = "选择上传文件", required = true) @RequestParam String taskId) {
        System.out.println("进入文件终止上传接口" + taskId);
        boolean b = fileService.stopProcess(taskId);
        return (b) ? ReturnData.ok("操作成功") : ReturnData.fail("文件已上传完成 取消上传失败");
    }

    /**
     * 获取上传任务id
     *
     * @param userId
     * @return
     */
    @ApiOperation(value = "获取上传任务ID", notes = "获取上传任务ID")
    @Authorized
    @PostMapping(value = "/taskId")
    public ReturnData getTaskId(@ApiIgnore @RequestAttribute String userId) {
        String taskId = fileService.getTaskId(userId);
        System.out.println("获取任务id成功" + taskId);
        return ReturnData.ok().setData(taskId);
    }


    /**
     * 创建文件夹
     *
     * @param folder
     * @return
     */
    @ApiOperation(value = "创建文件夹", notes = "创建文件夹")
    @Authorized
    @PutMapping(value = "/directory")
    public ReturnData buildDirectory(@ApiParam(" 示例：/ftptest 子目录示例：/ftptest/m") @RequestParam String folder) {
        FileVo result = fileService.buildDirectory(folder);
        return ReturnData.ok("操作成功").setData(result);
    }

    /**
     * 删除文件夹
     *
     * @param folder
     * @return
     */
    @ApiOperation(value = "删除文件夹(包含文件夹中的文件以及文件夹)", notes = "删除文件夹")
    @Authorized
    @DeleteMapping(value = "/directory")
    public ReturnData delDirectory(@ApiParam(" 示例：/ftptest 子目录示例：/ftptest/m") @RequestParam String folder, @ApiIgnore @RequestAttribute String userId) {
        boolean result = fileService.delDirectory(folder);
        RecordServiceImpl.insert(userId, "删除", folder, true, result);
        return (result) ? ReturnData.ok("成功").setData(true) : ReturnData.fail("失败");
    }

    /**
     * 删除文件
     *
     * @param url
     * @return
     */
    @ApiOperation(value = "删除文件", notes = "删除文件")
    @Authorized
    @DeleteMapping(value = "/file")
    public ReturnData delFile(@ApiParam(" 根目录示例：/01.jpg  多目录示例：/ftptest/xxx.jpg") @RequestParam String url, @ApiIgnore @RequestAttribute String userId) {
        boolean result = fileService.delFile(url);
        RecordServiceImpl.insert(userId, "删除", url, false, result);
        return (result) ? ReturnData.ok("成功").setData(true) : ReturnData.fail("失败");
    }

    /**
     * 重命名文件夹
     *
     * @param folder
     * @param newFolder
     * @return
     */
    @ApiOperation(value = "重命名文件夹", notes = "重命名文件夹")
    @Authorized
    @PutMapping(value = "/rename")
    public ReturnData renameFolder(@ApiParam(" 示例：/ftptest/c") @RequestParam String folder, @ApiParam(" 示例：/ftptest/b") @RequestParam String newFolder, @ApiIgnore @RequestAttribute String userId) {
        boolean result = fileService.renameFolder(folder, newFolder);
        RecordServiceImpl.insert(userId, "重命名", folder, true, result);
        return (result) ? ReturnData.ok("成功").setData(true) : ReturnData.fail("操作失败，文件夹不存在或已经被删除");
    }

    /**
     * 从ftp服务器上下载指定文件
     *
     * @param fileName
     * @return
     */
    @ApiOperation(value = "下载ftp服务器文件 以respose流的形式返回", notes = "下载文件")
    @Authorized
    @GetMapping(value = "/download", consumes = "application/octet-stream", produces = MediaType.APPLICATION_OCTET_STREAM_VALUE)
    public void download(@ApiParam(" 示例：/ftptest/c/xx.jpg") @RequestParam String fileName) {
        fileService.download(fileName, response);
    }


    /**
     * 根据文件名获取文件历史记录
     *
     * @param fileName
     * @return
     */
    @ApiOperation(value = "根据文件名获取文件历史记录", notes = "根据文件名获取文件历史记录")
    @Authorized
    @GetMapping(value = "/file/history")
    public ReturnData getFileHistory(@ApiParam("参数示例：/ftptest/c/xx.jpg") @RequestParam String fileName) {
        List<Records> records = fileService.getFileHistory(fileName);
        return ReturnData.ok(records);
    }

    /**
     * 在线预览功能使用openoffice转换成pdf文件响应流
     *
     * @param url 地址
     * @throws Exception
     */
    @ApiOperation(value = "文档在线预览接口")
    @GetMapping(value = "/file/online", consumes = "application/octet-stream", produces = MediaType.APPLICATION_OCTET_STREAM_VALUE)
    public void onlinePreview(@RequestParam("url") String url) throws Exception {
        fileService.onlinePreview(url, response);
    }

    /**
     * 根据指定目录下文件名模糊搜索文件名
     *
     * @param fileName
     */
    @ApiOperation(value = "通过文件名搜索文件")
    @Authorized
    @GetMapping(value = "/search")
    public ReturnData searchByFileName(@RequestParam String fileName, @RequestParam(required = false) String currentFolder) {
        List<FileVo> fileVos = fileService.searchByFileName(fileName, currentFolder);
        return ReturnData.ok().setData(fileVos);
    }

    /**
     * 拖拽移动文件/文件夹  到指定的目录
     *
     * @param fileOrDir    文件名/文件夹
     * @param targetFolder 目标文件夹
     * @return
     */
    @ApiOperation(value = "拖拽移动文件或文件夹")
    @Authorized
    @PutMapping(value = "/move")
    public ReturnData moveFileOrDir(@RequestParam String fileOrDir, @RequestParam String targetFolder) {
        boolean b = fileService.moveFileOrDir(fileOrDir, targetFolder);
        return b ? ReturnData.ok("操作成功") : ReturnData.fail("失败");
    }

    /**
     * 下载压缩包文件夹
     *
     * @param dir
     * @return
     */
    @ApiOperation(value = "下载压缩文件包", notes = "下载压缩文件包")
    @Authorized
    @GetMapping(value = "/zip")
    public void downloadZip(@RequestParam String dir) {
        fileService.downloadZip(dir, response);
    }


    /**
     * 提供给用户端单独服务做远程调用(预留接口)
     *
     * @param dir
     * @return
     */
    @ApiOperation(value = "下载文件夹，返回zip响应流", notes = "下载文件夹，返回zip响应流",hidden = true)
    @GetMapping(value = "/directoryInput")
    public void downloadDirectory(@RequestParam String dir,HttpServletResponse response) {
       fileService.downloadDirectory(dir,response);
    }

    /**
     * 用户端使用 获取到远程文件夹 并在指定目录生成文件夹(预留接口)
     *
     * @param dir       下载的目录
     * @param targetDir 生成文件目标目录
     * @return
     */
    @ApiOperation(value = "下载文件夹，(请求远程服务获取zip流 并解压生成目录结构文件至本地)", notes = "下载文件夹，(请求远程服务获取zip流 并生成目录结构文件至本地)",hidden = true)
    @GetMapping(value = "/directory")
    public ReturnData createLocalDir(@RequestParam String dir, @RequestParam String targetDir) {
        return fileService.createLocalDir(dir, targetDir);
    }


}
